package at.donalfonso.fahrer;

import java.io.Serializable;
import java.util.Random;

import javax.jms.JMSException;
import javax.jms.Message;
import javax.jms.MessageConsumer;
import javax.jms.MessageProducer;
import javax.jms.ObjectMessage;
import javax.jms.Queue;
import javax.jms.Topic;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import at.donalfonso.model.LieferBestellung;
import at.donalfonso.model.LieferBestellungStatus;
import at.donalfonso.utility.JMSUtility;

public class FahrerJMS extends Thread {


	private Logger logger = LoggerFactory.getLogger(this.getClass());
	private JMSUtility jmsUtility = null;

	private int filiale;
	private String name;
	
	private int waitTime = 3000;
	
	/**
	 * Ein Fahrer wartet auf fertige Lieferbestellungen und liefert diese
	 * an die angegeben Adresse. 
	 * Der Status (erfolgreich/gescheitet) wird an das Pizzagui gemeldet.
	 */
	public static void main(String[] args) {
		FahrerJMS fahrer;
		if (args.length < 2) {
			System.out.println("Usage: java Fahrer <ID> <FILIAL_ID> [<WAIT>]");
			fahrer = new FahrerJMS("F" + new Random().nextInt(100), 1); 
		}
		else {
			fahrer = new FahrerJMS(args[0], Integer.parseInt(args[1]));
		}

		if (args.length >2 && args[2] != null){
			fahrer.setWaitTime(0);
		}
		
		fahrer.run();
	}

	public FahrerJMS(String name, int filiale) {
		this.name = name;
		this.filiale = filiale;
	}

	public void setWaitTime(int time){
		waitTime = time;
	}
	
	public void run() {
		System.out.println("Fahrer: "+name + " ("+filiale+") - waitTime: "+waitTime);
		
		try{
			getJMSUtility().getConnection().start();

			Queue queue = getJMSUtility().getQueueBestellungFertig();
			String selector = "Class = '"+LieferBestellung.class.getSimpleName()+"'";
			MessageConsumer consumer = getJMSUtility().getSession().createConsumer(queue, selector);
			Message msg = null;
			
			
			while(true){
								
				//System.out.println("Warte auf Lieferbestellung ...");
				msg = consumer.receive();
				//System.out.println("Message erhalten: "+msg);
				
				if (! (msg instanceof ObjectMessage)) {
					System.out.println("ERROR: Keine Object Message.");
				}
				
				Serializable obj = ((ObjectMessage) msg).getObject();
					
				if (obj instanceof LieferBestellung){
					// die Bestellung wird ausgeliefert.
					LieferBestellung bestellung = (LieferBestellung) obj;
					
					bestellung.setFahrer(name);
					bestellung.setLieferstatus(LieferBestellungStatus.WIRD_GELIEFERT);
					updateGui(bestellung);
					
					/*
					//Pizzen aus der Queue entnehmen.
					for(Pizza pizza: bestellung.getPizzen()){
						selector = "ID = '"+pizza.getId()+"'";
						
						queue = getJMSUtility().getQueueKuecheOutput();
						consumer = getJMSUtility().getSession().createConsumer(queue, selector);
						Message message = consumer.receive(); 

						//updateGui(pizza);
					}
					
					*/
					Thread.sleep(waitTime);

					if (bestellung.adresseExistiert()){
						String adress = bestellung.getAdresse();
// TODO 20130610 sfu: Fahrer sollte Adress-Queue nicht selbst erzeugen, sondern vorhandene
//						Queue des KundeThreadJMS auf Kunden-ActiveMQ Nutzen
						queue = getJMSUtility().getSession().createQueue(adress);
						MessageProducer producer = getJMSUtility().getSession().createProducer(queue);
						msg = getJMSUtility().getSession().createObjectMessage(bestellung);
						producer.send(msg);
						
						bestellung.setLieferstatus(LieferBestellungStatus.ERFOLGREICH);
						System.out.println(name+" erfolgreich zugestellt: "+bestellung.getBestellungId());
						updateGui(bestellung);
					}else{
						// Fehler melden.
						bestellung.setLieferstatus(LieferBestellungStatus.GESCHEITERT);
						updateGui(bestellung);
					}					
				}else{
					System.out.println("! Fahrer hat ein Objekt erhalten das keine Lieferbestellung ist: FEHLER "+msg);
				}
			}
		}catch (JMSException e){
			
		} catch (InterruptedException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
	
	public JMSUtility getJMSUtility(){
		if (jmsUtility == null){
			jmsUtility = new JMSUtility(filiale);
		}
		return jmsUtility;
	}
	

	/**
	 * Über das Topic "Gui_update" werden Statusänderungen kommuniziert.
	 */
	public void updateGui(Serializable object){
		
		logger.debug("Updating Gui.");
		
		try {
			Topic topic = getJMSUtility().getTopicGuiUpdate();
			Message msg = getJMSUtility().getSession().createObjectMessage(object);
			msg.setStringProperty("Class", object.getClass().getSimpleName());
			
			MessageProducer producer = getJMSUtility().getSession().createProducer(topic);
			
			producer.send(msg);
			
			producer.close();
			
		} catch (JMSException e) {
			
			logger.debug("GUI Update failed.");
			
			e.printStackTrace();
		}	
	}
}
